package com.hannah.benchmark;

import java.util.concurrent.TimeUnit;

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;

@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
@Fork(1)
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
public class JSBenchmark {

	private Invocable arithInv;

	private Invocable objectInv;

	@Setup
	public void init() {
		ScriptEngineManager manager = new ScriptEngineManager();
		try {
			ScriptEngine engine = manager.getEngineByName("js");
			engine.eval("function testArith(a, b, c, d){return (a+b-c)*d;}");
			arithInv = (Invocable) engine;
			
			engine = manager.getEngineByName("js");
			engine.eval("function testObject(a, b, c, d){var object={f1: a, f2: a+b, f3: c, f4: (a+b-c)*d}; return object;}");
			objectInv = (Invocable) engine;
		} catch (ScriptException e) {
			e.printStackTrace();
		}
		System.out.println("准备工作就绪！");
	}

	@Benchmark
	public void testArith() throws Exception {
		Object result = arithInv.invokeFunction("testArith", 23342423, 435454, 121243, 23);
//		System.out.println(result);
	}

	@Benchmark
	public void testObject() throws Exception {
		Object result = objectInv.invokeFunction("testObject", 23342423, 435454, 121243, 23);
//		System.out.println(result);
	}

	public static void main(String[] args) throws Exception {
		JSBenchmark bm = new JSBenchmark();
		bm.init();
		bm.testObject();
	}

}
